package ${actionPackage};

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import ${dtoPackage}.${po.name}DTO;
import ${voPackage}.${po.name}VO;
import ${servicePackage}.${po.name}Service;
<#list po.relOneList as rel>
import ${voPackage}.${rel.name}VO;
</#list>
<#list po.relManyList as rel>
import ${voPackage}.${rel.name}VO;
</#list>

import com.odianyun.project.query.PageQueryArgs;
import com.odianyun.project.query.QueryArgs;
import com.odianyun.project.model.vo.ObjectResult;
<#if po.relOneList?size gt 0 || po.relManyList?size gt 0>
import com.odianyun.project.model.vo.ListResult;
</#if>
import com.odianyun.project.model.vo.PageResult;
import com.odianyun.project.model.vo.Result;
import com.odianyun.project.support.base.controller.BaseController;
import com.odianyun.db.query.PageVO;
import com.odianyun.project.support.data.expt.DataExporter;
<#if exportAsync?boolean>
import com.odianyun.project.support.data.expt.ExportContext;
</#if>
import com.odianyun.project.support.data.impt.DataImportHelper;
import com.odianyun.project.support.data.impt.DataImporter;
<#if importAsync?boolean>
import com.odianyun.project.support.data.impt.ImportContext;
<#else>
import com.odianyun.project.support.data.IDataStorage;
</#if>
<#if exportAsync?boolean || importAsync?boolean>
import com.odianyun.project.support.data.task.DataTask;
</#if>
import com.odianyun.project.support.data.model.DataExportParam;

import ${importPackage}.${po.name}ImportHandler;
import ${exportPackage}.${po.name}ExportHandler;
import com.odianyun.project.util.WebUtils;
import com.odianyun.util.date.DateUtils;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.util.*;

@Api(description="${po.title}")
@RequestMapping("${po.uncapitalizedName}")
@RestController
public class ${po.name}Action extends BaseController {
    @Resource
    private ${po.name}Service service;
    @Resource
    private DataImporter dataImporter;
    @Resource
    private DataExporter dataExporter;
    @Resource
    private ${po.name}ImportHandler importHandler;
    @Resource
    private ${po.name}ExportHandler exportHandler;
    <#if ! importAsync?boolean>
    @Resource
    private IDataStorage dataStorage;
    </#if>

    @ApiOperation(value="分页查询", notes="{filters:{\"key1\":value1, \"key2\":[value2]},sort:[{field:\"createTime\",asc:false}],page:1,limit:10}")
    @PostMapping("/listPage")
    public PageResult<${po.name}VO> listPage(@RequestBody PageQueryArgs args) {
        PageVO<${po.name}VO> vo = service.listPage(args);

        return PageResult.ok(vo);
    }

    @ApiOperation("查询")
    @GetMapping("/getById")
    public ObjectResult<${po.name}VO> getById(@RequestParam("id") Long id) {
        ${po.name}VO vo = service.getById(id);
        <#list po.relOneList as rel>
        vo.set${rel.name}(service.get${rel.name}(vo.get${rel.mainField.capName}()));
        </#list>
        <#list po.relManyList as rel>
        vo.set${rel.name}List(service.list${rel.name}(vo.get${rel.mainField.capName}()));
        </#list>

        return ObjectResult.ok(vo);
    }
        <#list po.relOneList as rel>

    @ApiOperation("查询${rel.title}")
    @GetMapping("/get${rel.name}")
    public ObjectResult<${rel.name}VO> get${rel.name}(@RequestParam("${rel.mainField.name}") ${rel.mainField.typeName} ${rel.mainField.name}) {
        return ObjectResult.ok(service.get${rel.name}(${rel.mainField.name}));
    }
        </#list>
        <#list po.relManyList as rel>

    @ApiOperation("查询${rel.title}")
    @GetMapping("/list${rel.name}")
    public ListResult<${rel.name}VO> list${rel.name}(@RequestParam("${rel.mainField.name}") ${rel.mainField.typeName} ${rel.mainField.name}) {
        return ListResult.ok(service.list${rel.name}(${rel.mainField.name}));
    }
        </#list>

    @ApiOperation("添加")
    @PostMapping("/add")
    public ObjectResult<Long> add(@RequestBody @Valid ${po.name}DTO u) throws Exception {
        notNull(u);

        return ObjectResult.ok(service.addWithTx(u));
    }

    @ApiOperation("修改")
    @PostMapping("/update")
    public Result update(@RequestBody @Valid ${po.name}DTO u) throws Exception {
        notNull(u);
        fieldNotNull(u, "id");

        service.updateWithTx(u);
        return Result.OK;
    }

    @ApiOperation("删除")
    @PostMapping("/delete")
    public Result delete(@RequestBody Long[] ids) throws Exception {
        notNull(ids);

        service.deletesWithTx(ids);
        return Result.OK;
    }
    <#if po.importable>

    @ApiOperation("导入")
    @PostMapping("/importData")
    <#if importAsync?boolean>
	public ObjectResult<DataTask> importData(MultipartHttpServletRequest request) throws Exception {
        MultipartFile multipartFile = request.getFile("file");
        Map<String, Object> param = WebUtils.getParameterMap(request);

        ImportContext ctx = dataImporter.importData(importHandler, DataImportHelper.createDataImportParam(multipartFile, param));
        DataTask t = (DataTask) ctx.get("task");
        return ObjectResult.ok(t);
    }
    <#else>
	public ObjectResult<Map<String, Object>> importData(MultipartHttpServletRequest request) throws Exception {
        MultipartFile multipartFile = request.getFile("file");
        Map<String, Object> param = WebUtils.getParameterMap(request);

        DataImportResult<${po.name}DTO> result = dataImporter.importDataSkipErrorSync(importHandler, DataImportHelper.createDataImportParam(multipartFile, param));
        String failedFile = null;
        if (result.hasError()) {
            failedFile = dataStorage.write(result.getFilename(), (os) -> {
                try {
                    DataImportHelper.writeErrorFile(result, os, false);
                } catch (Exception e) {
                    throw ExceptionUtils.wrap2Runtime(e);
                }
            });
        }
        return ObjectResult.okForMap("failedUrl", failedFile,
                "totalSize", result.getData().size(),
                "successSize", result.getSuccessCount());
    }
    </#if>
    </#if>
    <#if po.exportable>

    @ApiOperation("导出")
    @PostMapping("/exportData")
    <#if exportAsync?boolean>
    public ObjectResult<DataTask> exportData(@RequestBody QueryArgs args, HttpServletRequest request, HttpServletResponse response) throws Exception {
        DataExportParam param = new DataExportParam("${po.title!po.name}_" + DateUtils.date2Str(new Date(), "yyyyMMddHHmmss") + ".xlsx");
        Map<String, Object> maps = new HashMap<>();
        maps.put("args", args);
        param.setParameters(maps);
        ExportContext ctx = dataExporter.exportData(exportHandler, param);
        DataTask t = (DataTask) ctx.get("task");
        return ObjectResult.ok(t);
    }
    <#else>
    public void exportData(@RequestBody QueryArgs args, HttpServletRequest request, HttpServletResponse response) throws Exception {
        DataExportParam param = new DataExportParam("${po.title!po.name}_" + DateUtils.date2Str(new Date(), "yyyyMMddHHmmss") + ".xlsx");
        Map<String, Object> maps = new HashMap<>();
        maps.put("args", args);
        param.setParameters(maps);
        WebUtils.setXlsxAttachmentHeader(request, response, param.getExportFileName());
        dataExporter.exportDataSync(exportHandler, param, response.getOutputStream());
    }
    </#if>
    </#if>
	
}
